package com.jing.mycontentprovider;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.jing.mycontentprovider.adapter.ContactsAdapter;

public class ContactsActivity extends AppCompatActivity {

    private static final int REQUEST_CONTACTS_PERMISSION = 1;
    private static final int REQUEST_PICK_CONTACT_OF_UPDATE = 2;

    private static final int REQUEST_PICK_CONTACT_OF_DELETE = 3;

    private RecyclerView contactsRecyclerView;
    private ContactsAdapter contactsAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_contacts);

        contactsRecyclerView = findViewById(R.id.contacts_recycler_view);
        contactsRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        Button addContactButton = findViewById(R.id.add_contact_button);
        Button editContactButton = findViewById(R.id.edit_contact_button);
        Button deleteContactButton = findViewById(R.id.delete_contact_button);

        addContactButton.setOnClickListener(v -> addContact());
        editContactButton.setOnClickListener(v -> pickContactForEditing());
        deleteContactButton.setOnClickListener(v -> pickContactForDeletion());

        //检查联系人权限
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_CONTACTS_PERMISSION);
        } else {
            //读取联系人信息
            loadContacts();
        }
    }

    private void openAddMyDialogFrom() {
        // 创建自定义对话框
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        View dialogView = getLayoutInflater().inflate(R.layout.my_dialog_layout, null);
        builder.setView(dialogView);

        EditText editName = dialogView.findViewById(R.id.edit_name);
        EditText editPhone = dialogView.findViewById(R.id.edit_phone);
        Button btnConfirm = dialogView.findViewById(R.id.btn_confirm);
        Button btnCancel = dialogView.findViewById(R.id.btn_cancel);

        AlertDialog dialog = builder.create();

        btnConfirm.setOnClickListener(v -> {
            String newName = editName.getText().toString();
            String newPhone = editPhone.getText().toString();
            addContact(newName, newPhone);
            dialog.dismiss();
        });

        btnCancel.setOnClickListener(v -> dialog.dismiss());

        dialog.show();
    }

    private void addContact(String name, String phone) {
        //用来存储原始联系人的数据。
        ContentValues values = new ContentValues();
        //联系人账户类型的字段，通常用于指定该联系人是哪个账户,设置为 null 表示联系人没有指定账户或是本地联系人。
        values.put(ContactsContract.RawContacts.ACCOUNT_TYPE, (String) null);
        //这是联系人账户名称的字段，通常用于指定该联系人是哪个账户,设置为 null 同样表示联系人没有指定账户或是本地联系人。
        values.put(ContactsContract.RawContacts.ACCOUNT_NAME, (String) null);

        //getContentResolver().insert(): 通过 ContentResolver 的 insert() 方法将数据插入到指定的内容 URI 中。
        //ContactsContract.RawContacts.CONTENT_URI: 这是原始联系人数据的内容 URI，表示联系人记录的表。插入数据时使用此 URI。
        //insert() 方法会返回一个 Uri 对象，表示新插入记录的 URI。这个 URI 包含了新记录的唯一标识符（ID）。
        Uri rawContactUri = getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values);

        //从返回的 Uri 中提取路径的最后一部分，这部分是新插入记录的 ID。
        long rawContactId = Long.parseLong(rawContactUri.getLastPathSegment());


        // 添加联系人姓名
        //创建 ContentValues 对象: 用于存储将要插入的数据。
        ContentValues nameValues = new ContentValues();
        //设置联系人 ID: 将 rawContactId 作为原始联系人 ID。
        nameValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
        //设置 MIME 类型: 指定数据的类型为联系人姓名。
        nameValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
        //设置姓名: 将用户输入的姓名作为联系人姓名存储。
        nameValues.put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
        //插入数据: 将 ContentValues 插入到 ContactsContract.Data.CONTENT_URI 指定的内容 URI 中。
        getContentResolver().insert(ContactsContract.Data.CONTENT_URI, nameValues);

        // 添加联系人电话
        ContentValues phoneValues = new ContentValues();
        phoneValues.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
        phoneValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
        phoneValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
        phoneValues.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
        getContentResolver().insert(ContactsContract.Data.CONTENT_URI, phoneValues);

        loadContacts();
    }

    private void openUpdateMyDialogFrom(String contactId) {
        //定义查询的列
        //ContactsContract.Data.MIMETYPE: 数据的 MIME 类型，用于确定数据的具体类型。
        //ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME: 联系人的显示名称。
        //ContactsContract.CommonDataKinds.Phone.NUMBER: 联系人的电话号码。
        String[] projection = new String[]{
                ContactsContract.Data.MIMETYPE,
                ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
                ContactsContract.CommonDataKinds.Phone.NUMBER
        };

        // 查询姓名

        //getContentResolver().query(): 用于查询内容提供者的 query() 方法。这会返回一个 Cursor 对象，表示查询结果。
        //ContactsContract.Data.CONTENT_URI: 查询的内容 URI，表示联系人数据表。
        //projection: 查询中需要返回的列。
        //ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?": 查询的 selection 条件。这里是查询条件，? 是占位符。
        //new String[]{contactId, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE}: selection 条件中的参数替换占位符。contactId 是指定的联系人的 ID，ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE 指定查询姓名数据。
        //null: 排序条件，这里没有排序。
        Cursor nameCursor = getContentResolver().query(
                ContactsContract.Data.CONTENT_URI,
                projection,
                ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?",
                new String[]{contactId, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE},
                null
        );
        //从 Cursor 对象中提取联系人的姓名
        String name = null;
        if (nameCursor != null) {
            if (nameCursor.moveToFirst()) {
                //nameCursor: 这是一个 Cursor 对象，表示查询结果集。它包含了从内容提供者中检索到的数据。
                //getColumnIndex(String columnName): 这个方法用于获取指定列的索引（即列的位置）。columnName 是你要检索的列的名称。
                //ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME: 这是列名，表示联系人的显示名称。你通过这个列名来查询列的索引。
                name = nameCursor.getString(nameCursor.getColumnIndex(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME));
            }
            nameCursor.close();
        }

        // 查询电话号码
        Cursor phoneCursor = getContentResolver().query(
                ContactsContract.Data.CONTENT_URI,
                projection,
                ContactsContract.Data.CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?",
                new String[]{contactId, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE},
                null
        );

        String phone = null;
        if (phoneCursor != null) {
            if (phoneCursor.moveToFirst()) {
                phone = phoneCursor.getString(phoneCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
            }
            phoneCursor.close();
        }

        // 显示或使用联系人信息
        if (name != null && phone != null) {
            Toast.makeText(this, "Name: " + name + "\nPhone: " + phone, Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(this, "No details found", Toast.LENGTH_SHORT).show();
        }
        // 创建自定义对话框
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        View dialogView = getLayoutInflater().inflate(R.layout.my_dialog_layout, null);
        builder.setView(dialogView);

        EditText editName = dialogView.findViewById(R.id.edit_name);
        EditText editPhone = dialogView.findViewById(R.id.edit_phone);
        Button btnConfirm = dialogView.findViewById(R.id.btn_confirm);
        Button btnCancel = dialogView.findViewById(R.id.btn_cancel);

        if (name != null) {
            editName.setText(name);
        }
        if (phone != null) {
            editPhone.setText(phone);
        }

        AlertDialog dialog = builder.create();

        btnConfirm.setOnClickListener(v -> {
            String newName = editName.getText().toString();
            String newPhone = editPhone.getText().toString();
            //去修改联系人信息
            updateContact(contactId, newName, newPhone);
            dialog.dismiss();
        });

        btnCancel.setOnClickListener(v -> dialog.dismiss());

        dialog.show();
    }

    private void updateContact(String contactId, String newName, String newPhone) {

        // 更新姓名
        ContentValues nameValues = new ContentValues();
        nameValues.put(ContactsContract.Data.RAW_CONTACT_ID, contactId);
        nameValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
        nameValues.put(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, newName);

        // 更新电话号码
        ContentValues phoneValues = new ContentValues();
        phoneValues.put(ContactsContract.Data.RAW_CONTACT_ID, contactId);
        phoneValues.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
        phoneValues.put(ContactsContract.CommonDataKinds.Phone.NUMBER, newPhone);
        //ContactsContract.CommonDataKinds.Phone.TYPE: 这是一个列名，表示电话号码的类型。例如，家庭、工作、移动等。
        //ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE: 这是一个常量，表示电话号码的类型是“移动电话”。这使得更新后的电话号码被标记为移动号码。
        phoneValues.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);


        // 使用 ContentResolver 更新数据
        getContentResolver().update(
                ContactsContract.Data.CONTENT_URI,
                nameValues,
                ContactsContract.Data.RAW_CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?",
                new String[]{contactId, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE}
        );
        //where条件改为 ContactsContract.Data.RAW_CONTACT_ID + " = ? ",new String[]{contactId} 同一个联系人下有多个联系方式时会出现混乱
        //唯一性: 如果你只用 RAW_CONTACT_ID，可能会更新与该联系人 ID 相关的所有数据类型（如姓名、电话号码、电子邮件等），而不仅仅是电话号码。这会导致数据混乱，尤其是在联系人有多个电话号码或不同类型的联系方式时。
        //准确性: 加上 MIMETYPE 条件可以确保你只更新特定类型的数据（如电话号码），而不会影响同一联系人的其他信息。

        getContentResolver().update(
                ContactsContract.Data.CONTENT_URI,
                phoneValues,
                ContactsContract.Data.RAW_CONTACT_ID + " = ? AND " + ContactsContract.Data.MIMETYPE + " = ?",
                new String[]{contactId, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE}
        );

        // 重新加载联系人
        loadContacts();
    }


    private void loadContacts() {
        Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
        contactsAdapter = new ContactsAdapter(cursor);
        contactsRecyclerView.setAdapter(contactsAdapter);
    }
//打开系统新建联系人界面
    private void openContactCreation() {
        Intent intent = new Intent(Intent.ACTION_INSERT);
        intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
        startActivity(intent);
    }

    private void addContact() {
        //二选一
        //使用系统自带方法添加联系人
//        openContactCreation();
        //使用自定义对话框添加联系人
        openAddMyDialogFrom();
    }

    private void pickContactForEditing() {
        //Intent.ACTION_PICK 是一个动作常量，表示用户要选择某项数据（在这里是联系人）。
        //ContactsContract.Contacts.CONTENT_URI 是联系人内容提供者的 URI（统一资源标识符），它指向所有联系人数据的集合。
        Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
        startActivityForResult(intent, REQUEST_PICK_CONTACT_OF_UPDATE);
    }

    private void pickContactForDeletion() {
        Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
        startActivityForResult(intent, REQUEST_PICK_CONTACT_OF_DELETE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_PICK_CONTACT_OF_UPDATE && resultCode == RESULT_OK && data != null) {
            //从 Intent 对象中获取 Uri。这个 Uri 代表了用户选择的联系人的数据。
            Uri contactUri = data.getData();
            //从 Uri 中提取最后一部分，通常是联系人的唯一 ID。
            String contactId = contactUri.getLastPathSegment();
            //使用自定义修改联系人
            openUpdateMyDialogFrom(contactId);
//            // 使用意图打开联系人编辑界面
//            Intent intent = new Intent(Intent.ACTION_EDIT);
//            intent.setData(ContactsContract.Contacts.CONTENT_URI.buildUpon().appendPath(contactId).build());
//            startActivity(intent);
        } else if (requestCode == REQUEST_PICK_CONTACT_OF_DELETE && resultCode == RESULT_OK && data != null) {
            Uri contactUri = data.getData();
            String contactId = contactUri.getLastPathSegment();

            // 删除联系人的具体操作
            //ContactsContract.RawContacts.CONTENT_URI: 这是联系人内容提供者的 URI，表示原始联系人数据的集合。它是用来访问和操作联系人的基础 URI。
            //buildUpon(): 创建一个 Uri.Builder 对象，用于修改或构建新的 URI。
            //appendPath(contactId): 在现有 URI 的末尾追加联系人 ID。这样可以指定要操作的特定联系人。例如，如果原始 URI 是 content://com.android.contacts/raw_contacts，追加 contactId 后的 URI 可能是 content://com.android.contacts/raw_contacts/123，其中 123 是联系人 ID。
            //build(): 生成修改后的 URI。在这个例子中，最终的 URI 表示要删除的特定联系人。
            Uri deleteUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon().appendPath(contactId).build();
            int rowsDeleted = getContentResolver().delete(deleteUri, null, null);
            if (rowsDeleted > 0) {
                Toast.makeText(this, "成功删除该联系人", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "联系人删除失败", Toast.LENGTH_SHORT).show();
            }
            // 更新联系人列表
            loadContacts();
        }
    }


    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        //判断请求码
        if (requestCode == REQUEST_CONTACTS_PERMISSION) {
            //返回权限请求结果
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //加载联系人数据
                loadContacts();
            } else {
                Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
            }
        }
    }
}
